import 'dart:async';
import 'dart:typed_data';
import 'dart:ui' as ui;

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';

class BlurImageDemo extends StatefulWidget {
  BlurImageDemo({Key? key}) : super(key: key);

  @override
  State<BlurImageDemo> createState() => _BlurImageDemoState();
}

class _BlurImageDemoState extends State<BlurImageDemo> {
  late ui.Image fillImage;
  var sliderValue = 0.0;
  bool isImageLoaded = false;
  var blurValue = 0.0;

  void initState() {
    super.initState();
    init();
  }

  Future<void> init() async {
    final ByteData data = await rootBundle.load('images/island-coder.png');
    fillImage = await loadImage(Uint8List.view(data.buffer));
  }

  Future<ui.Image> loadImage(Uint8List img) async {
    final Completer<ui.Image> completer = Completer();
    ui.decodeImageFromList(img, (ui.Image img) {
      setState(() {
        isImageLoaded = true;
      });
      return completer.complete(img);
    });
    return completer.future;
  }

  @override
  Widget build(BuildContext context) {
    if (this.isImageLoaded) {
      return Stack(
        alignment: AlignmentDirectional.bottomStart,
        children: [
          CustomPaint(
            painter: BlurImagePainter(
              bgImage: fillImage,
              blur: blurValue,
            ),
            child: Container(
              width: MediaQuery.of(context).size.width,
              height: MediaQuery.of(context).size.height,
            ),
          ),
          Center(
            child: Container(
              alignment: Alignment.center,
              width: 800,
              height: 500,
              decoration: BoxDecoration(
                color: Colors.white.withOpacity(0.8),
                borderRadius: BorderRadius.circular(10.0),
              ),
              child: Material(
                color: Colors.transparent,
                child: Text(
                  '模糊效果',
                  style: TextStyle(
                    fontSize: 36.0,
                    color: Colors.black87,
                    fontWeight: FontWeight.bold,
                  ),
                  textAlign: TextAlign.center,
                ),
              ),
            ),
          ),
          Container(
            height: 40.0,
            child: Material(
              child: Slider(
                value: sliderValue,
                min: 0.0,
                max: 20.0,
                onChanged: (value) {
                  sliderValue = value;
                  setState(
                    () {},
                  );
                },
                onChangeEnd: (value) {
                  setState(
                    () {
                      blurValue = value;
                    },
                  );
                },
              ),
            ),
          ),
        ],
      );
    } else {
      return CircularProgressIndicator();
    }
  }
}

class BlurImagePainter extends CustomPainter {
  final ui.Image bgImage;
  final double blur;

  BlurImagePainter({
    required this.bgImage,
    required this.blur,
  });
  @override
  void paint(Canvas canvas, Size size) {
    var paint = Paint();
    // 模糊的取值不能为0，为0会抛异常
    if (blur > 0) {
      paint.imageFilter = ui.ImageFilter.blur(
        sigmaX: blur,
        sigmaY: blur,
        tileMode: TileMode.mirror,
      );
    }

    canvas.drawImageRect(
      bgImage,
      Rect.fromLTRB(0, 0, bgImage.width.toDouble(), bgImage.height.toDouble()),
      Offset.zero & size,
      paint,
    );
  }

  @override
  bool shouldRepaint(covariant CustomPainter oldDelegate) {
    return true;
  }
}
